package com.sia.springcloud.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sia.springcloud.heartbeat.HeartbeatApi;
import com.sia.springcloud.mapper.DeviceMapper;
import com.sia.springcloud.mapper.PointMapper;
import com.sia.springcloud.model.Device;
import com.sia.springcloud.model.Point;
import com.sia.springcloud.protocol.config.CollectApi;
import com.sia.springcloud.service.ICollectService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Author: Sirius
 * @Date: 2021/12/21 1:20
 * @Description: 通信协议数采服务接口实现类
 * 主要提供的方法：开启数采、关闭数采、写入变量
 **/
@Slf4j
@Service("CollectServiceImpl")
public class CollectServiceImpl implements ICollectService {

    @Resource
    private DeviceMapper deviceMapper;

    @Resource
    private PointMapper pointMapper;

    @Resource
    private CollectApi collectApi;


    @Value("${topic.name}")
    private String TopicName;


    /**
     * 开启指定Id的设备的数采任务
     * <p>
     * 注意：每次发来一次数采请求后都会返回一次心跳请求更新
     *
     * 设置了三个通道，供其选择
     *
     * @param deviceId 设备id
     * @return 返回是否开启
     * 如果返回true，说明开启数采成功
     * 如果返回false，说明开启数采失败
     */
    public boolean startCollect(String deviceId) {
        Device device = deviceMapper.selectById(deviceId);

        QueryWrapper<Point> pointQueryWrapper = new QueryWrapper<>();
        pointQueryWrapper.eq("device_id", deviceId);
        List<Point> pointList = pointMapper.selectList(pointQueryWrapper);

        try {
            ////设置传输通道，之后需要进行调整
            //String topicName;
            //
            //// 设置数量为count的传输通道，按照device_id % count的结果来进行选择不同的传输通道
            //int num = device.getId()%3+1;
            //
            //if(num<=2){
            //    topicName = "modbus0"+num;
            //}else{
            //    topicName ="modbus03";
            //}

            if (collectApi.startCollect(device, pointList, TopicName)) {

                log.info("设备 " + deviceId + " 开启数采成功");

                return true;
            } else {
                log.info("设备 " + deviceId + " 开启数采失败");
                return false;
            }
        } catch (Exception e) {
            log.error("设备 {} 在开启数采过程中发生异常，未开启数采", deviceId);
            log.error(e.getMessage());
            return false;
        }
    }


    /**
     * 关闭某个设备的数采
     * 说明：基于尽力而为的原则（即使没有关闭也有心跳自检来进行补救）
     *
     * @param deviceId
     * @return 返回是否关闭
     * 如果返回true，已经走完了关闭数采的流程，尽力关闭了
     * 如果返回false，说明关闭数采的过程中发生了异常
     */
    public boolean stopCollect(String deviceId) {
        Device device = deviceMapper.selectById(deviceId);

        QueryWrapper<Point> pointQueryWrapper = new QueryWrapper<>();
        pointQueryWrapper.eq("device_id", deviceId);
        List<Point> pointList = pointMapper.selectList(pointQueryWrapper);

        try {
            //只要调用停止数采方法中没有发生异常就返回true；
            log.info("准备为设备 {} 关闭数采，使用的协议为{}，", deviceId, device.getProtocolName());

            collectApi.stopCollect(device, pointList);

            return true;
        } catch (Exception e) {
            log.error("设备 {} 在关闭数采过程中发生异常，未成功关闭数采", deviceId);
            log.error(e.getMessage());
            return false;
        }
    }


    /**
     * 写变量
     * <p>
     * 暂未实现
     *
     * @param deviceId
     * @param value
     * @return
     */
    @RequestMapping("/writeVariable")
    public String writeVariable(String deviceId, String value) {
        return null;
    }

}
